home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 46 / Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso / -serious- / misc / dvi2tty-5.1 / disdvi.c < prev    next >
C/C++ Source or Header  |  1999-09-06  |  16KB  |  587 lines

  1. /*****************************************************************************/
  2. /*                                                                           */
  3. /*   disdvi  ---  disassembles TeX dvi files.                                */
  4. /*                                                                           */
  5. /*                                                                           */
  6. /*   2.23 23jul95 M.J.E. Mol     Cleanups from duz@roxi.ez.fht-mannheim.de   */
  7. /*   2.22 13dec90 M.J.E. Mol     Fixed bug in num(). Cleaned up code.        */
  8. /*   2.21 03may90 M.J.E. Mol     Created usage().                            */
  9. /*    2.2 02may90 M.J.E. Mol     Included port to VAX/VMS VAXC by            */
  10. /*                               Robert Schneider.                           */
  11. /*    2.1 19jan90 M.J.E. Mol     Maintain a list of fonts and                */
  12. /*                               show fontnames in font changes.             */
  13. /*                               Show character code when printing ligatures */
  14. /*    2.0 23jan89 M.J.E. Mol (c) 1989                                       */
  15. /*                                               marcel@duteca.et.tudelft.nl */
  16. /*                                                                           */
  17. /*****************************************************************************/
  18.  
  19.  
  20. char *disdvi = "@(#) disdvi.c  2.23 23/07/95 M.J.E. Mol (c) 1989, 1990 - 1995";
  21.  
  22. /*
  23.  * Include files
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #if defined(MSDOS)
  29. #include <fcntl.h>
  30. #else
  31. #include <unistd.h>
  32. #endif
  33. #include <ctype.h>
  34. #include <string.h>
  35. #include "commands.h"
  36.  
  37.  
  38. /*
  39.  * Constant definitions
  40.  */
  41.  
  42. #define LASTCHAR        127    /* max dvi character, above are commands    */
  43.  
  44. #define get1()           num(1)
  45. #define get2()           num(2)
  46. #define get3()           num(3)
  47. #define get4()           num(4)
  48. #define sget1()         snum(1)
  49. #define sget2()         snum(2)
  50. #define sget3()         snum(3)
  51. #define sget4()         snum(4)
  52.  
  53.  
  54.  
  55. /*
  56.  * Type definitions
  57.  */
  58.  
  59. typedef struct _font {
  60.     long    num;
  61.     struct _font * next;
  62.     char  * name;
  63. } font;
  64.  
  65.  
  66.  
  67. /*
  68.  * Variable declarations
  69.  */
  70.  
  71. font * fonts = NULL;
  72. FILE * dvifp;
  73. char * dvi_name;
  74. long   pc = 0;
  75.  
  76. char * progname;
  77.  
  78.  
  79. /*
  80.  * Function declarations
  81.  */
  82.  
  83. char *          malloc          ();
  84.  
  85. #if defined(VMS)
  86.                 main            (int argc, char ** argv);
  87. #else
  88. void            main            (int argc, char ** argv);
  89. #endif
  90. void            bop             (void);
  91. void            preamble        (void);
  92. void            postamble       (void);
  93. void            postpostamble   (void);
  94. void            fontdef         (int x);
  95. char *          fontname        (long fntnum);
  96. void            special         (int x);
  97. void            printnonprint   (int ch);
  98. unsigned long   num             (int size);
  99. long            snum            (int size);
  100. void            usage           (void);
  101.  
  102.  
  103.  
  104.  
  105. /*
  106.  * MAIN --
  107.  */
  108.  
  109. #if defined(VMS)
  110.      main(int argc, char **argv)
  111. #else
  112. void main(int argc, char **argv)
  113. #endif
  114. {
  115.     register int opcode;                /* dvi opcode                        */
  116.     register int i;
  117.     int fontnum;
  118.  
  119.     progname = *argv++;
  120.  
  121.     if (argc > 2) {
  122.         fprintf(stderr, "To many arguments\n");
  123.         usage();
  124.         exit(1);
  125.     }
  126.  
  127.     if (argc == 2) {
  128.         if (!strcmp(*argv, "-h")) {
  129.             usage();
  130.             exit(0);
  131.         }
  132.         if ((i = strlen(*argv)) == 0) {
  133.             fprintf(stderr, "Illegal empty filename\n");
  134.             usage();
  135.             exit(2);
  136.         }
  137.         if ((i >= 5) && (!strcmp(*argv+i-4, ".dvi")))
  138.             dvi_name = *argv;
  139.         else {
  140.             dvi_name = malloc((i+5) * sizeof(char));
  141.             strcpy(dvi_name, *argv);
  142.             strcat(dvi_name, ".dvi");
  143.         }
  144.         if ((dvifp = fopen(dvi_name, "r")) == NULL) {
  145.             perror(dvi_name);
  146.             exit(3);
  147.         }
  148.     }
  149.     else
  150.         dvifp = stdin;
  151.  
  152. #if defined(MSDOS)
  153.     setmode(fileno(dvifp), O_BINARY);
  154. #endif
  155.  
  156.     while ((opcode = (int) get1()) != EOF) {    /* process until end of file */
  157.         printf("%06ld: ", pc - 1);
  158.         if ((opcode <= LASTCHAR) && isprint(opcode)) {
  159.             printf("Char:     ");
  160.             while ((opcode <= LASTCHAR) && isprint(opcode)) {
  161.                 putchar(opcode);
  162.                 opcode = (int) get1();
  163.             }
  164.             putchar('\n');
  165.             printf("%06ld: ", pc - 1);
  166.         }
  167.  
  168.         if (opcode <= LASTCHAR) 
  169.             printnonprint(opcode);              /* it must be a non-printable */
  170.         else if ((opcode >= FONT_00) && (opcode <= FONT_63)) 
  171.             printf("FONT_%02d              /* %s */\n", opcode - FONT_00,
  172.                                     fontname(opcode - FONT_00));
  173.         else
  174.             switch (opcode) {
  175.                 case SET1     :
  176.                 case SET2     : 
  177.                 case SET3     :
  178.                 case SET4     : printf("SET%d:    %ld\n", opcode - SET1 + 1,
  179.                                                        num(opcode - SET1 + 1));
  180.                                 break;
  181.                 case SET_RULE : printf("SET_RULE: height: %ld\n", sget4());
  182.                                 printf("%06ld: ", pc);
  183.                                 printf("          length: %ld\n", sget4());
  184.                                 break;
  185.                 case PUT1     :
  186.                 case PUT2     :
  187.                 case PUT3     :
  188.                 case PUT4     : printf("PUT%d:     %ld\n", opcode - PUT1 + 1,
  189.                                                        num(opcode - PUT1 + 1));
  190.                                 break;
  191.                 case PUT_RULE : printf("PUT_RULE: height: %ld\n", sget4());
  192.                                 printf("%06ld: ", pc);
  193.                                 printf("          length: %ld\n", sget4());
  194.                                 break;
  195.                 case NOP      : printf("NOP\n");  break;
  196.                 case BOP      : bop();            break;
  197.                 case EOP      : printf("EOP\n");  break;
  198.                 case PUSH     : printf("PUSH\n"); break;
  199.                 case POP      : printf("POP\n");  break;
  200.                 case RIGHT1   :
  201.                 case RIGHT2   : 
  202.                 case RIGHT3   : 
  203.                 case RIGHT4   : printf("RIGHT%d:   %ld\n", opcode - RIGHT1 + 1,
  204.                                                      snum(opcode - RIGHT1 + 1));
  205.                                 break;
  206.                 case W0       : printf("W0\n");   break;
  207.                 case W1       : 
  208.                 case W2       :
  209.                 case W3       :
  210.                 case W4       : printf("W%d:       %ld\n", opcode - W0,
  211.                                                       snum(opcode - W0));
  212.                                 break;
  213.                 case X0       : printf("X0\n");   break;
  214.                 case X1       :
  215.                 case X2       :
  216.                 case X3       :
  217.                 case X4       : printf("X%d:       %ld\n", opcode - X0,
  218.                                                       snum(opcode - X0));
  219.                                 break;
  220.                 case DOWN1    : 
  221.                 case DOWN2    : 
  222.                 case DOWN3    :
  223.                 case DOWN4    : printf("DOWN%d:    %ld\n", opcode - DOWN1 + 1,
  224.                                                       snum(opcode - DOWN1 + 1));
  225.                                 break;
  226.                 case Y0       : printf("Y0\n");   break;
  227.                 case Y1       :
  228.                 case Y2       :
  229.                 case Y3       :
  230.                 case Y4       : printf("Y%d:       %ld\n", opcode - Y0,
  231.                                                       snum(opcode - Y0));
  232.                                 break;
  233.                 case Z0       : printf("Z0\n");   break;
  234.                 case Z1       :
  235.                 case Z2       :
  236.                 case Z3       : 
  237.                 case Z4       : printf("Z%d:       %ld\n", opcode - Z0,
  238.                                                       snum(opcode - Z0));
  239.                                 break;
  240.                 case FNT1     :
  241.                 case FNT2     :
  242.                 case FNT3     :
  243.                 case FNT4     : fontnum = num(opcode -FNT1 + 1);
  244.                                 printf("FNT%d:     %ld    /* %s */\n",
  245.                                        opcode - FNT1 + 1, fontnum,
  246.                                        fontname(fontnum));
  247.                                 break;
  248.                 case XXX1     : 
  249.                 case XXX2     : 
  250.                 case XXX3     :
  251.                 case XXX4     : special(opcode - XXX1 + 1);     break;
  252.                 case FNT_DEF1 :
  253.                 case FNT_DEF2 :
  254.                 case FNT_DEF3 :
  255.                 case FNT_DEF4 : fontdef(opcode - FNT_DEF1 + 1); break;
  256.                 case PRE      : preamble();                     break;
  257.                 case POST     : postamble();                    break;
  258.                 case POST_POST: postpostamble();                break;
  259.             }
  260.     }
  261.  
  262.     exit(0);
  263.  
  264. } /* main */
  265.  
  266.  
  267.  
  268. /*
  269.  * BOP -- Process beginning of page.
  270.  */
  271.  
  272. void bop(void)
  273. {
  274.     int i;
  275.  
  276.     printf("BOP       page number      : %ld", sget4());
  277.     for (i=9; i > 0; i--) {
  278.         if (i % 3 == 0)
  279.             printf("\n%06ld:         ", pc);
  280.         printf("  %6ld", sget4()); 
  281.     }
  282.     printf("\n%06ld: ", pc);
  283.     printf("          prev page offset : %06ld\n", sget4()); 
  284.  
  285.     return;
  286.  
  287. } /* bop */
  288.  
  289.  
  290.  
  291. /*
  292.  * POSTAMBLE -- Process post amble.
  293.  */
  294.  
  295. void postamble(void) 
  296. {
  297.  
  298.     printf("POST      last page offset : %06ld\n", sget4());
  299.     printf("%06ld: ", pc);
  300.     printf("          numerator        : %ld\n", get4());
  301.     printf("%06ld: ", pc);
  302.     printf("          denominator      : %ld\n", get4());
  303.     printf("%06ld: ", pc);
  304.     printf("          magnification    : %ld\n", get4());
  305.     printf("%06ld: ", pc);
  306.     printf("          max page height  : %ld\n", get4());
  307.     printf("%06ld: ", pc);
  308.     printf("          max page width   : %ld\n", get4());
  309.     printf("%06ld: ", pc);
  310.     printf("          stack size needed: %d\n", (int) get2());
  311.     printf("%06ld: ", pc);
  312.     printf("          number of pages  : %d\n", (int) get2());
  313.  
  314.     return;
  315.  
  316. } /* postamble */
  317.  
  318.  
  319.  
  320. /*
  321.  * PREAMBLE -- Process pre amble.
  322.  */
  323.  
  324. void preamble(void)
  325. {
  326.     register int i;
  327.  
  328.     printf("PRE       version          : %d\n", (int) get1());
  329.     printf("%06ld: ", pc);
  330.     printf("          numerator        : %ld\n", get4());
  331.     printf("%06ld: ", pc);
  332.     printf("          denominator      : %ld\n", get4());
  333.     printf("%06ld: ", pc);
  334.     printf("          magnification    : %ld\n", get4());
  335.     printf("%06ld: ", pc);
  336.     i = (int) get1();
  337.     printf("          job name (%3d)   :", i);
  338.     while (i-- > 0)
  339.         putchar((int) get1());
  340.     putchar('\n');
  341.  
  342.     return;
  343.  
  344. } /* preamble */
  345.  
  346.  
  347.  
  348. /*
  349.  * POSTPOSTAMBLE -- Process post post amble.
  350.  */
  351.  
  352. void postpostamble(void)
  353. {
  354.     register int i;
  355.  
  356.     printf("POSTPOST  postamble offset : %06ld\n", get4());
  357.     printf("%06ld: ", pc);
  358.     printf("          version          : %d\n", (int) get1());
  359.     while ((i = (int) get1()) == TRAILER) {
  360.         printf("%06ld: ", pc - 1);
  361.         printf("TRAILER\n");
  362.     }
  363.     while (i != EOF) {
  364.         printf("%06ld: ", pc - 1);
  365.         printf("BAD DVI FILE END: 0x%02X\n", i);
  366.         i = (int) get1();
  367.     }
  368.  
  369.     return;
  370.  
  371. } /* postpostamble */
  372.  
  373.  
  374.  
  375. /*
  376.  * SPECIAL -- Process special opcode.
  377.  */
  378.  
  379. void special(int x)
  380. {
  381.     register long len;
  382.  
  383.     len = num(x);
  384.     printf("XXX%d:     %ld bytes\n", x, len);
  385.     printf("%06ld: ", pc);
  386.     for (; len>0; len--)           /* a bit dangerous ... */
  387.         putchar((int) get1());     /*   can be non-printables */
  388.     putchar('\n');
  389.  
  390.     return;
  391.  
  392. } /* special */
  393.  
  394.  
  395.  
  396. /*
  397.  * FONTDEF -- Process a font definition.
  398.  */
  399.  
  400. void fontdef(int x)
  401. {
  402.     register int i;
  403.     char * name;
  404.     font * fnt;
  405.     int namelen;
  406.     long fntnum;
  407.     int new = 0;
  408.  
  409.     fntnum = num(x);
  410.     printf("FNT_DEF%d: %ld\n", x, fntnum);
  411.     printf("%06ld: ", pc);           /* avoid side-effect on pc in get4() */
  412.     printf("          checksum         : %ld\n", get4());
  413.     printf("%06ld: ", pc);
  414.     printf("          scale            : %ld\n", get4());
  415.     printf("%06ld: ", pc);
  416.     printf("          design           : %ld\n", get4());
  417.     printf("%06ld: ", pc);
  418.     printf("          name             : ");
  419.     namelen = (int) get1() + (int) get1();
  420.     fnt = fonts;
  421.     while (fnt != NULL && fnt->num != fntnum)
  422.         fnt = fnt->next;
  423.     if (fnt == NULL) {
  424.         if ((fnt = (font *) malloc(sizeof(font))) == NULL) {
  425.             perror("fontdef");
  426.             exit(1);
  427.         }
  428.         fnt->num = fntnum;
  429.         new = 1;
  430.     }
  431.     else
  432.         free(fnt->name);    /* free old name */
  433.     if ((name = (char *) malloc(namelen * sizeof(char))) == NULL) {
  434.         perror("fontdef");
  435.         exit(1);
  436.     }
  437.     
  438.     for (i = 0; i < namelen; i++)
  439.         name[i] = get1();
  440.     fnt->name = name;
  441.     if (new) {
  442.         fnt->next = fonts;
  443.         fonts = fnt;
  444.     }
  445.  
  446.     printf("%s\n", name);
  447.  
  448.     return;
  449.  
  450. } /* fontdef */
  451.  
  452.  
  453.  
  454. /*
  455.  * FONTNAME -- Return font name.
  456.  */
  457.  
  458. char * fontname(long fntnum)
  459. {
  460.     font * fnt;
  461.  
  462.     fnt = fonts;
  463.     while (fnt != NULL && fnt->num != fntnum)
  464.         fnt = fnt->next;
  465.     if (fnt != NULL)
  466.         return fnt->name;
  467.  
  468.     return "unknown fontname";
  469.    
  470. } /* fontname */
  471.  
  472.  
  473.  
  474. /*
  475.  * PRINTNONPRINT -- Translate non-printable characters.
  476.  */
  477.  
  478. void printnonprint(int ch)
  479. {
  480.  
  481.     printf("Char:     ");
  482.     switch (ch) {
  483.         case 11  :  printf("ff         /* ligature (non-printing) 0x%02X */",
  484.                            ch);
  485.                     break;
  486.         case 12  :  printf("fi         /* ligature (non-printing) 0x%02X */",
  487.                            ch);
  488.                     break;
  489.         case 13  :  printf("fl         /* ligature (non-printing) 0x%02X */",
  490.                            ch);
  491.                     break;
  492.         case 14  :  printf("ffi        /* ligature (non-printing) 0x%02X */",
  493.                            ch);
  494.                     break;
  495.         case 15  :  printf("ffl        /* ligature (non-printing) 0x%02X */",
  496.                            ch);
  497.                     break;
  498.         case 16  :  printf("i          /* (non-printing) 0x%02X */", ch);
  499.                     break;
  500.         case 17  :  printf("j          /* (non-printing) 0x%02X */", ch);
  501.                     break;
  502.         case 25  :  printf("ss         /* german (non-printing) 0x%02X */", ch);
  503.                     break;
  504.         case 26  :  printf("ae         /* scadinavian (non-printing) 0x%02X */",
  505.                            ch);
  506.                     break;
  507.         case 27  :  printf("oe         /* scadinavian (non-printing) 0x%02X */",
  508.                            ch);
  509.                     break;
  510.         case 28  :  printf("o          /* scadinavian (non-printing) 0x%02X */",
  511.                            ch);
  512.                     break;
  513.         case 29  :  printf("AE         /* scadinavian (non-printing) 0x%02X */",
  514.                            ch);
  515.                     break;
  516.         case 30  :  printf("OE         /* scadinavian (non-printing) 0x%02X */",
  517.                            ch);
  518.                     break;
  519.         case 31  :  printf("O          /* scadinavian (non-printing) 0x%02X */",
  520.                            ch);
  521.                     break;
  522.         default  :  printf("0x%02X", ch); break;
  523.     }
  524.     putchar('\n');
  525.  
  526.     return;
  527.  
  528. } /* printnonprint */
  529.  
  530.  
  531.  
  532. /*
  533.  * NUM --
  534.  */
  535.  
  536. unsigned long num(int size)
  537. {
  538.     register int i;
  539.     register long x = 0;
  540.  
  541.     pc += size;
  542.     for (i = size; i > 0; i--)
  543.         x = (x << 8) + (unsigned) getc(dvifp);
  544.  
  545.     return x;
  546.  
  547. } /* num */
  548.  
  549.  
  550.  
  551. /*
  552.  * SNUM --
  553.  */
  554.  
  555. long snum(int size)
  556. {
  557.     register int i;
  558.     register long x = 0;
  559.  
  560.     pc += size;
  561.     x = getc(dvifp);
  562.     if (x & 0x80)
  563.         x -= 0x100;
  564.     for (i = size - 1; i > 0; i--)
  565.         x = (x << 8) + (unsigned) getc(dvifp);
  566.  
  567.     return x;
  568.  
  569. } /* snum */
  570.  
  571.  
  572.  
  573. /*
  574.  * USAGE --
  575.  */
  576.  
  577. void usage(void)
  578. {
  579.  
  580.     fprintf(stderr, "\n%s\n\n", disdvi);
  581.     fprintf(stderr, "    disassembles TeX dvi files\n");
  582.     fprintf(stderr, "Usage: %s [-h | <dvi-file>[.dvi]]\n", progname);
  583.  
  584.     return;
  585.  
  586. } /* usage */
  587.